package yxy.game.pm2.module.avatar;

import org.joda.time.DateTime;
import org.redisson.api.RMap;
import org.redisson.api.RSet;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.title;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.module.BaseGameRedisLockBean;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;

import java.util.*;


public class TitleModule extends BaseGameRedisLockBean {

    // bean===========================================================================

    private String dataCode;
    private boolean newfound;
    private DateTime expiryDate;

    public String getDataCode() {
        return dataCode;
    }

    public void setDataCode(String dataCode) {
        this.dataCode = dataCode;
    }

    public DateTime getExpiryDate() {
        return expiryDate;
    }

    public void setExpiryDate(DateTime expiryDate) {
        this.expiryDate = expiryDate;
    }

    public boolean isNewfound() {
        return newfound;
    }

    public void setNewfound(boolean newfound) {
        this.newfound = newfound;
    }

    // func==========================================================================

    static public Collection<Integer> newfound(String playerCode) {
        ArrayList<Integer> list = new ArrayList<>();
        Collection<TitleModule> all = all(playerCode);
        String lockKey = lockKey(playerCode);

        try {
            if (tryLock(lockKey)) {

                //最新
                for (TitleModule module : all) {
                    if (module.isNewfound()) {
                        list.add(Integer.parseInt(module.getDataCode()));
                        module.setNewfound(false);
                        set(playerCode, module);
                    }
                }

                //兼容
                Collection<String> oldAll = oldTouch(playerCode).readAll();
                for (String code : oldAll) {
                    list.add(Integer.parseInt(code));
                }
                oldTouch(playerCode).clear();

                new TipHandle().updateTip(playerCode, TipType.主公_称号切页, false);
            }
        } catch (Exception e) {
        } finally {
            unlock(lockKey);
        }

        return list;
    }

    // redis==========================================================================


    //弃用
    static public String oldKey(String playerCode) {
        return String.format("PLAYER:%s:MODULE:TITLE", playerCode);
    }

    static private RSet<String> oldTouch(String playerCode) throws RedisException {
        RSet<String> rSets = redis().client().getSet(oldKey(playerCode));
        return rSets;
    }

    //需求更改，需要加上过期时间，旧key弃用
    static public String key(String playerCode) {
        return String.format("PLAYER:%s:MODULE:TITLENEW", playerCode);
    }


    static private RMap<String, TitleModule> touch(String playerCode) throws RedisException {
        return redis().client().getMap(key(playerCode));
    }

    static public Collection<TitleModule> all(String playerCode) {
        ArrayList<TitleModule> list = new ArrayList<>();
        String lockKey = lockKey(playerCode);
        try {
            if (tryLock(lockKey)) {
                Collection<TitleModule> all = touch(playerCode).readAllValues();
                for (TitleModule module : all) {
                    if (module.update(playerCode) != null) {
                        list.add(module);
                    }
                }
            }
        } catch (Exception e) {
        } finally {
            unlock(lockKey);
        }
        return list;
    }

    private TitleModule update(String playerCode) {
        if (getExpiryDate() != null && DateTime.now().isAfter(getExpiryDate())) {
            // 头像框过期
            remove(playerCode, getDataCode());
            try {
                new CurrencyHandle().cost(playerCode, null, Currency.create(CurrencyType.CT_称号, Integer.parseInt(getDataCode()), 1));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        return this;
    }


    static public void add(String playerCode, title title) {
        try {
            title data = DataCenter.getData(title.getId(), title.class);

            TitleModule module = TitleModule.get(playerCode, data.getCode());
            if (module == null) {
                module = new TitleModule();
                module.setDataCode(data.getCode());
                new CurrencyHandle().addCurrency(playerCode, CCReason.竞技场, Currency.create(CurrencyType.CT_称号, data.getId(), 1));
            }
            module.setNewfound(true);
            if (data.getTerm() > 0) {
                module.setExpiryDate(DateTime.now().plusHours(data.getTerm()));
            } else {
                module.setExpiryDate(null);
            }

            set(playerCode, module);
            new TipHandle().updateTip(playerCode, TipType.主公_称号切页, true);
        } catch (Exception e) {
        }
    }

    static public void remove(String playerCode, String code) {
        try {
            touch(playerCode).remove(code);
        } catch (RedisException e) {
        }
    }

    static private TitleModule set(String playerCode, TitleModule module) {
        try {
            touch(playerCode).put(module.getDataCode(), module);
        } catch (RedisException e) {
        }
        return module;
    }

    static private TitleModule get(String playerCode, String code) {
        try {
            TitleModule module = touch(playerCode).get(code);
            return module;
        } catch (Exception e) {
            return null;
        }
    }

    // lock==========================================================================

    static private String lockKey(String playerCode) {
        return String.format("lock:%s", key(playerCode));
    }

}
